package com.hzhh123.crypto.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.KeyGenerator;
import java.security.SecureRandom;
import java.security.Security;

/**
 * @author hzhh123
 * @version 1.0
 * @date 2022/4/13 14:04
 * @des
 */
public class Sm4Utils {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static String encryptHex(String str, String keyHex) {
        SymmetricCrypto sm4 = new SymmetricCrypto("SM4", Hex.decode(keyHex));
        return sm4.encryptHex(str);
    }

    public static String encryptBase64(String str, String keyBase64) {
        SymmetricCrypto sm4 = new SymmetricCrypto("SM4", Base64.decode(keyBase64));
        return Base64.encode(sm4.encrypt(str));
    }

    public static String decryptHex(String str, String keyHex) {
        SymmetricCrypto sm4 = new SymmetricCrypto("SM4", Hex.decode(keyHex));
        return sm4.decryptStr(str);
    }

    public static String decryptBase64(String str, String keyBase64) {
        SymmetricCrypto sm4 = new SymmetricCrypto("SM4", Base64.decode(keyBase64));
        return sm4.decryptStr(str);
    }

    public static byte[] generateKey() throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance("SM4", BouncyCastleProvider.PROVIDER_NAME);
        kg.init(128, new SecureRandom());
        return kg.generateKey().getEncoded();
    }

    public static String generateKeyHex() throws Exception {
        byte[] key = generateKey();
        return Hex.toHexString(key);
    }

    public static String generateKeyBase64() throws Exception {
        byte[] key = generateKey();
        return Base64.encode(key);
    }

    public static String encrypt(String str, String key) {
        byte[] keyBytes = Validator.isHex(key) ? HexUtil.decodeHex(key) : Base64.decode(key);
        SymmetricCrypto sm4 = new SymmetricCrypto("SM4", keyBytes);
        return Validator.isHex(key) ? sm4.encryptHex(str) : Base64.encode(sm4.encrypt(str));
    }

    public static String decrypt(String str, String key) {
        byte[] keyBytes = Validator.isHex(key) ? HexUtil.decodeHex(key) : Base64.decode(key);
        SymmetricCrypto sm4 = new SymmetricCrypto("SM4", keyBytes);
        return sm4.decryptStr(str);
    }

    public static void main(String[] args) throws Exception {
        //ea3f9e5432e4f21d4b01a4e6a6ee95be
        //System.out.println(generateKeyHex());
        ////+AW6W7ARusZ18QKDoASBkA==
        //System.out.println(generateKeyBase64());
        //String keyHex = "ea3f9e5432e4f21d4b01a4e6a6ee95be";
        //String keyBase64 = "+AW6W7ARusZ18QKDoASBkA==";
        //String encryptHex = encryptHex("java123", keyHex);
        //String encryptBase64 = encryptBase64("java123", keyBase64);
        //System.out.println(encryptHex);
        //System.out.println(encryptBase64);
        //String base64 = decryptBase64(encryptBase64, keyBase64);
        //String decryptHex = decryptHex(encryptHex, keyHex);
        //System.out.println(base64);
        //System.out.println(decryptHex);
        //
        //String encryptHex1 = encrypt("java123", keyHex);
        //String encryptBase641 = encrypt("java123", keyBase64);
        //System.out.println(encryptHex1);
        //System.out.println(encryptBase641);
        //String base641 = decrypt(encryptBase641, keyBase64);
        //String decryptHex1 = decryptHex(encryptHex1, keyHex);
        //System.out.println(base641);
        //System.out.println(decryptHex1);
        //
        //String encodeStr="6d59f8e45d3c30726f42d249aef5286f857a6a2cfa735aa7ed34c56238052f9869919df32bed051cd3ec3eef647a2f2e";
        //String key="ea3f9e5432e4f21d4b01a4e6a6ee95be";
        //System.out.println(decrypt(encodeStr,key));

    }
}
